home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / board / IGNUChess151.lha / GNUChess-1.51 / Intuidsp.c < prev    next >
C/C++ Source or Header  |  1994-02-10  |  36KB  |  1,498 lines

  1. /************************************************************************/
  2. /* IntuiDsp.c --- Intuition Interface for GNU Chess                        */
  3. /************************************************************************/
  4.  
  5. static const char *Version = "$VER: IGNUChess 1.51 " __AMIGADATE__;
  6.  
  7. #include <exec/types.h>
  8. #include <exec/memory.h>
  9.  
  10. #include <dos.h>
  11.  
  12. #include <libraries/diskfont.h>
  13. #include <libraries/gadtools.h>
  14. #include <libraries/asl.h>
  15.  
  16. #include <proto/exec.h>
  17. #include <proto/dos.h>
  18. #include <proto/diskfont.h>
  19. #include <proto/graphics.h>
  20. #include <proto/intuition.h>
  21. #include <proto/gadtools.h>
  22. #include <proto/asl.h>
  23.  
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <signal.h>
  28. #include <time.h>
  29.  
  30. #include "Global.h"
  31. #include "gfx.h"
  32. #include "Proto.h"
  33. #include "Interface.h"
  34. #include "gnuchess.h"
  35.  
  36. /* -------------------------------------------------------------------- */
  37. /* Minimal library version for SAS/C auto open library feature            */
  38. /* -------------------------------------------------------------------- */
  39.  
  40. long __oslibversion = 37;
  41.  
  42. /* -------------------------------------------------------------------- */
  43. /* static function prototypes                                            */
  44. /* -------------------------------------------------------------------- */
  45.  
  46. static void    Die(int);
  47. static void    TerminateSearch(int);
  48. static void    UpdateClocks(void);
  49. static int    parse(FILE *, unsigned short *, short);
  50. static void    GetGame(void);
  51. static void    SaveGame(void);
  52. static void ListGame(void);
  53. static void    Undo(void);
  54. static void    ChangeAlphaWindow(void);
  55. static void    ChangeBetaWindow(void);
  56. static void    GiveHint(void);
  57. static void ChangeSearchDepth(void);
  58. static void SetContempt(void);
  59. static void ChangeXwindow(void);
  60. static void    DoDebug(void);
  61. static void    ShowPostnValues(void);
  62. static void ShowError(int);
  63.  
  64. /* -------------------------------------------------------------------- */
  65.  
  66. unsigned int            tmbuf1[2],
  67.                         tmbuf2[2];
  68. long                    time1,
  69.                         time2;
  70.  
  71. struct Screen            *s;
  72. struct ViewPort            *vp;
  73. APTR                    vi;
  74. struct Window            *w;
  75. struct RastPort            *rp;
  76. struct FileRequester    *freq;
  77. struct Remember            *rk;
  78. ULONG                    DisplayID;
  79.  
  80. static ULONG NewLook[] = { ~0 };
  81.  
  82. static struct ColorSpec ColorSpec[] = {
  83.     { COLOR_BCK    , 0x0B, 0x0B, 0x08 },
  84.     { COLOR_RAHMEN , 0x00, 0x00, 0x00 },
  85.     { COLOR_WFIG   , 0x0F, 0x0F, 0x0F },
  86.     { COLOR_REQBAR , 0x0C, 0x0C, 0x0A },
  87.     { COLOR_EMPTY  , 0x0C, 0x0B, 0x08 },
  88.     { COLOR_SFIG   , 0x06, 0x05, 0x02 },
  89.     { COLOR_WFELD  , 0x0A, 0x08, 0x01 },
  90.     { COLOR_SFELD  , 0x0E, 0x0D, 0x0A },
  91.     { COLOR_MENUBCK, 0x00, 0x05, 0x08 },
  92.     { COLOR_BLOCK  , 0x0D, 0x0D, 0x0B },
  93.     { COLOR_TXTBCK , 0x0E, 0x0E, 0x0C },
  94.     { COLOR_TXTFGR , 0x00, 0x00, 0x00 },
  95.     { COLOR_REQBCK , 0x08, 0x08, 0x01 },
  96.     { COLOR_MARK   , 0x0C, 0x04, 0x00 },
  97.     { COLOR_FMARK  , 0x0C, 0x04, 0x00 },
  98.     { -1, 0x00, 0x00, 0x00 }
  99. };
  100.  
  101. #define FONTFLAGS (FPF_ROMFONT | FPF_DISKFONT | FPF_DESIGNED)
  102.  
  103. static struct TextFont    *TF_Times15,
  104.                         *TF_Times18,
  105.                         *TF_Courier15;
  106.  
  107. struct TextAttr    TA_Times15        = { "times.font"  , 15, FS_NORMAL, FONTFLAGS },
  108.                 TA_Times18        = { "times.font"  , 18, FS_NORMAL, FONTFLAGS },
  109.                 TA_Courier15    = { "courier.font", 15, FSF_BOLD , FONTFLAGS };
  110.  
  111. // Graphic-offsets for texts
  112.  
  113. int    off_comp_left,        // "Computer"
  114.     off_comp_right,
  115.     off_human_left,        // "Human"
  116.     off_human_right,    //  *** smile ***
  117.     off_clock_left,        // clocks
  118.     off_clock_right,
  119.     off_algbr_left,        // notation
  120.     off_algbr_right;
  121.  
  122. /* -------------------------------------------------------------------- */
  123. /* Fit texts into text boxes, parameter `where` is for placement into    */
  124. /* left or right column                                                    */
  125. /* -------------------------------------------------------------------- */
  126.  
  127. #define LEFT    0
  128. #define RIGHT    1
  129.  
  130. static int CalcTextFit(char *s, int where)
  131. {
  132.     ULONG    enable;
  133.  
  134.     SetFont(rp, TF_Courier15);
  135.     enable = AskSoftStyle(rp);
  136.     SetSoftStyle(rp, FSF_BOLD, enable);
  137.  
  138.     if ( where == LEFT )
  139.         return       ( NX2 - NX1 )   / 4 - TextLength(rp, s, strlen(s)) / 2;
  140.     else
  141.         return ( 3 * ( NX2 - NX1 ) ) / 4 - TextLength(rp, s, strlen(s)) / 2;
  142. }
  143.  
  144. static void Fit_All_Text(void)
  145. {
  146.     off_comp_left        = CalcTextFit("Computer" , LEFT );
  147.     off_comp_right        = CalcTextFit("Computer" , RIGHT);
  148.     off_human_left        = CalcTextFit("  Human  ", LEFT );
  149.     off_human_right        = CalcTextFit("  Human  ", RIGHT);
  150.     off_clock_left        = CalcTextFit("000:00:00", LEFT );
  151.     off_clock_right        = CalcTextFit("000:00:00", RIGHT);
  152.     off_algbr_left        = CalcTextFit("a1h8"     , LEFT );
  153.     off_algbr_right        = CalcTextFit("a1h8"     , RIGHT);
  154. }
  155.  
  156. /* -------------------------------------------------------------------- */
  157. /* Print text string s at coordinates (x, y)                            */
  158. /* -------------------------------------------------------------------- */
  159.  
  160. static void MyText(char *s, int x, int y)
  161. {
  162.     ULONG    enable;
  163.  
  164.     SetAPen(rp, COLOR_TXTFGR);
  165.     SetBPen(rp, COLOR_TXTBCK);
  166.     SetDrMd(rp, JAM2);
  167.     SetFont(rp, TF_Courier15);
  168.     enable = AskSoftStyle(rp);
  169.     SetSoftStyle(rp, FSF_BOLD, enable);
  170.     Move(rp, x, y);
  171.     Text(rp, s, strlen(s));
  172. }
  173.  
  174. /* -------------------------------------------------------------------- */
  175. /* Reset game variables to their default values                            */
  176. /* -------------------------------------------------------------------- */
  177.  
  178. #ifndef true
  179. #    define true        1
  180. #endif
  181. #ifndef false
  182. #    define false    0
  183. #endif
  184.  
  185. static void ResetVars(void)
  186. {
  187.     beep                =
  188.     hashflag            = true;
  189.     reverse                =
  190.     bothsides            =
  191.     post                = false;
  192.     
  193.     Awindow                =
  194.     Bwindow                =
  195.     xwndw                = 90;
  196.     MaxSearchDepth        = 29;
  197.  
  198.     opponent            = white;
  199.     computer            = black;
  200.  
  201.     ResetGfx();
  202. }
  203.  
  204. /* -------------------------------------------------------------------- */
  205. /* This is called once at program start to initialize graphics            */
  206. /* -------------------------------------------------------------------- */
  207.  
  208. void Initialize(void)
  209. {
  210.     int                        x, y;
  211.     DisplayInfoHandle        handle;
  212.     ULONG                    sw, sh;
  213.     int                        transfer;
  214.     struct DimensionInfo    di;
  215.  
  216.  
  217.     /* ---------------------------------------------------------------- */
  218.     /* Open Fonts                                                        */
  219.     /* ---------------------------------------------------------------- */
  220.  
  221.     if ( ! (TF_Times15   = OpenDiskFont(&TA_Times15  )) ) ExitChess(1);
  222.     if ( ! (TF_Times18   = OpenDiskFont(&TA_Times18  )) ) ExitChess(2);
  223.     if ( ! (TF_Courier15 = OpenDiskFont(&TA_Courier15)) ) ExitChess(3);
  224.  
  225.     /* ---------------------------------------------------------------- */
  226.     /* Open custom screen, assign ViewPort and VisualInfo vars            */
  227.     /* ---------------------------------------------------------------- */
  228.  
  229.     if ( ModeNotAvailable( DisplayID ) ) {
  230.         DisplayID = DEFAULT_MONITOR_ID | HIRESLACE_KEY;
  231.     }
  232.  
  233.     handle = FindDisplayInfo( DisplayID );
  234.     if ( ! handle ) ExitChess(13);
  235.  
  236.     transfer = GetDisplayInfoData(
  237.         handle,
  238.         (UBYTE *) &di,
  239.         sizeof(struct DimensionInfo),
  240.         DTAG_DIMS,
  241.         0
  242.     );
  243.     if ( ! transfer ) ExitChess(14);
  244.  
  245.     sw = (di.TxtOScan.MaxX - di.TxtOScan.MinX >= 680) ? STDSCREENWIDTH : 680;
  246.     sh = (di.TxtOScan.MaxY - di.TxtOScan.MinY >= 460) ? STDSCREENWIDTH : 460;
  247.  
  248.     s = OpenScreenTags(
  249.         NULL,
  250.         SA_Width,            sw,
  251.         SA_Height,            sh,
  252.         SA_Depth,            4,
  253.         SA_Colors,            ColorSpec,
  254.         SA_DetailPen,        COLOR_TXTFGR,
  255.         SA_BlockPen,        COLOR_BLOCK,
  256.         SA_Font,            &TA_Courier15,
  257.         SA_Title,            "Intuition GNU Chess interface",
  258.         SA_Type,            CUSTOMSCREEN,
  259.         SA_DisplayID,        DisplayID,
  260.         SA_Overscan,        OSCAN_TEXT,
  261.         SA_Pens,            NewLook,
  262.         SA_FullPalette,        TRUE,
  263.         SA_AutoScroll,        ( sw != STDSCREENWIDTH ) || ( sh != STDSCREENHEIGHT ),
  264.         TAG_DONE
  265.     );
  266.     if ( ! s ) ExitChess(4);
  267.  
  268.     vp = &(s->ViewPort);
  269.     vi = GetVisualInfo(s, TAG_DONE);
  270.  
  271.     /* ---------------------------------------------------------------- */
  272.     /* Open main window                                                    */
  273.     /* ---------------------------------------------------------------- */
  274.  
  275.     w = OpenWindowTags(
  276.         NULL,
  277.         WA_Left,            0,
  278.         WA_Top,                0,
  279.         WA_IDCMP,            IDCMP_MOUSEBUTTONS    |
  280.                             IDCMP_GADGETUP        |
  281.                             IDCMP_MENUPICK        |
  282.                             IDCMP_REQVERIFY        |
  283.                             IDCMP_INTUITICKS    |
  284.                             IDCMP_REFRESHWINDOW,
  285.         WA_CustomScreen,    s,
  286.         WA_Flags,            WFLG_ACTIVATE        |
  287.                             WFLG_BORDERLESS        |
  288.                             WFLG_BACKDROP        |
  289.                             WFLG_SMART_REFRESH,
  290.         WA_AutoAdjust,        TRUE,
  291.         TAG_DONE
  292.     );
  293.     if ( ! w ) ExitChess(5);
  294.  
  295.     rp = w->RPort;
  296.  
  297.     /* ---------------------------------------------------------------- */
  298.     /* Allocate ASL file requester                                        */
  299.     /* ---------------------------------------------------------------- */
  300.  
  301.     freq = (struct FileRequester *) AllocAslRequestTags(
  302.         ASL_FileRequest,
  303.         ASLFR_Window,            w,
  304.         ASLFR_InitialLeftEdge,    0,
  305.         ASLFR_InitialTopEdge,    24,
  306.         ASLFR_InitialWidth,        421,
  307.         ASLFR_InitialHeight,    421,
  308.         ASLFR_SleepWindow,        TRUE,
  309.         ASLFR_TextAttr,            &TA_Courier15,
  310.         ASLFR_RejectIcons,        TRUE,
  311.         TAG_DONE
  312.     );
  313.     if ( ! freq ) ExitChess(6);
  314.  
  315.     /* ---------------------------------------------------------------- */
  316.     /* Create and install menus                                            */
  317.     /* ---------------------------------------------------------------- */
  318.  
  319.     Menu = CreateMenus(
  320.         NM,
  321.         GTMN_FrontPen,        COLOR_TXTFGR,
  322.         GTMN_FullMenu,        TRUE,
  323.         TAG_DONE
  324.     );
  325.     if ( ! Menu ) ExitChess(7);
  326.  
  327.     if ( ! LayoutMenus(Menu, vi, GTMN_TextAttr, &TA_Courier15, TAG_DONE ) )
  328.         ExitChess(8);
  329.  
  330.     if ( ! SetMenuStrip(w, Menu) ) ExitChess(9);
  331.  
  332.     /* ---------------------------------------------------------------- */
  333.     /* Initialize Gadgets                                                */
  334.     /* ---------------------------------------------------------------- */
  335.  
  336.     InitGads();
  337.  
  338.     /* ---------------------------------------------------------------- */
  339.     /* Render basic graphics                                            */
  340.     /* ---------------------------------------------------------------- */
  341.  
  342.     SetRast(rp, COLOR_BCK);
  343.  
  344.     DrawBevelBox(
  345.         rp,
  346.         NX1 - 2,            NY1 - 2,
  347.         NX2 - NX1 + 5,        NY2 - NY1 + 5,
  348.         GT_VisualInfo,        vi,
  349.         TAG_DONE
  350.     );
  351.     DrawBevelBox(
  352.         rp,
  353.         NX1 - 1,            NY1 - 1,
  354.         NX2 - NX1 + 3,        NY2 - NY1 + 3,
  355.         GT_VisualInfo,        vi,
  356.         TAG_DONE
  357.     );
  358.     DrawBevelBox(
  359.         rp,
  360.         TX1 - 2,            TY1 - 2,
  361.         TX2 - TX1 + 5,        TY2 - TY1 + 5,
  362.         GT_VisualInfo,        vi,
  363.         TAG_DONE
  364.     );
  365.     DrawBevelBox(
  366.         rp,
  367.         TX1 - 1,            TY1 - 1,
  368.         TX2 - TX1 + 3,        TY2 - TY1 + 3,
  369.         GT_VisualInfo,        vi,
  370.         TAG_DONE
  371.     );
  372.  
  373.     SetAPen(rp, COLOR_TXTBCK);
  374.     RectFill(rp, NX1, NY1, NX2, NY2);
  375.     RectFill(rp, TX1, TY1, TX2, TY2);
  376.  
  377.     SetAPen(rp, COLOR_RAHMEN);
  378.     for ( y = -1; y <= 7; y++ ) {
  379.         Move(rp, XPOS(0)-2, YPOS(y)-1);
  380.         Draw(rp, XPOS(8)-1, YPOS(y)-1);
  381.         Move(rp, XPOS(0)-2, YPOS(y)-2);
  382.         Draw(rp, XPOS(8)-1, YPOS(y)-2);
  383.     }
  384.     for ( x = 0; x <= 8; x++ ) {
  385.         Move(rp, XPOS(x)-2, YPOS(-1)-1);
  386.         Draw(rp, XPOS(x)-2, YPOS( 7)-1);
  387.         Move(rp, XPOS(x)-1, YPOS(-1)-1);
  388.         Draw(rp, XPOS(x)-1, YPOS( 7)-1);
  389.     }
  390.  
  391.     Fit_All_Text();
  392.     ResetVars();
  393. }
  394.  
  395. /* -------------------------------------------------------------------- */
  396. /* Clean up, de-allocate everything opened at runtime, exit gracefully    */
  397. /* -------------------------------------------------------------------- */
  398.  
  399. void ExitChess( int error )
  400. {
  401.     if ( error            ) ShowError( error );
  402.     if ( w                ) { ClearMenuStrip(w); CloseWindow(w); }
  403.     if ( Menu            )     FreeMenus(Menu);
  404.                               FreeGads();
  405.     if ( vi                )    FreeVisualInfo(vi);
  406.     if ( s                )    CloseScreen(s);
  407.     if ( freq            )    FreeAslRequest((APTR) freq);
  408.     if ( TF_Courier15    )    CloseFont(TF_Courier15);
  409.     if ( TF_Times15        )    CloseFont(TF_Times15);
  410.     if ( TF_Times18        )    CloseFont(TF_Times18);
  411.     if ( rk                )    FreeRemember(&rk, TRUE);
  412.     exit(0);
  413. }
  414.  
  415. /* -------------------------------------------------------------------- */
  416. /* This function is called every time the user is prompted for a move.    */
  417. /* -------------------------------------------------------------------- */
  418.  
  419. void InputCommand(void)
  420. {
  421.     short                ok,
  422.                         i;
  423.     long                cnt,
  424.                         rate,
  425.                         t1,
  426.                         t2;
  427.     unsigned short        mv;
  428.     char                s[5]        = "a1a1",
  429.                         line[40];
  430.     struct IntuiMessage    *msg;
  431.     int                    selected    = FALSE,
  432.                         toggle        = TRUE,
  433.                         sq1            = 0,
  434.                         sq2,
  435.                         mustredraw    = FALSE;
  436.  
  437.     ok        =
  438.     quit    = false;
  439.     player    = opponent;
  440.     ft        = 0;
  441.  
  442.     /* ---------------------------------------------------------------- */
  443.     /* Main input event selector loop                                    */
  444.     /* ---------------------------------------------------------------- */
  445.  
  446.     while ( ! ( ok || quit ) ) {
  447.         WaitPort(IDCMPORT);
  448.         msg = GT_GetIMsg(IDCMPORT);
  449.         switch ( CLASS(msg) ) {
  450.  
  451.             /* -------------------------------------------------------- */
  452.             /* Refresh window event, required for GadTools                */
  453.             /* -------------------------------------------------------- */
  454.  
  455.             case IDCMP_REFRESHWINDOW:
  456.                 GT_BeginRefresh(w);
  457.                 GT_EndRefresh(w, TRUE);
  458.                 break;
  459.  
  460.             /* -------------------------------------------------------- */
  461.             /* Intuiticks, used for blinking selected square            */
  462.             /* -------------------------------------------------------- */
  463.  
  464.             case IDCMP_INTUITICKS:
  465.                 if ( selected ) {
  466.                     if ( toggle )
  467.                         SetRGB4(
  468.                             vp,
  469.                             COLOR_FMARK,
  470.                             ColorSpec[COLOR_RAHMEN].Red,
  471.                             ColorSpec[COLOR_RAHMEN].Green,
  472.                             ColorSpec[COLOR_RAHMEN].Blue
  473.                         );
  474.                     else
  475.                         SetRGB4(
  476.                             vp,
  477.                             COLOR_FMARK,
  478.                             ColorSpec[COLOR_FMARK].Red,
  479.                             ColorSpec[COLOR_FMARK].Green,
  480.                             ColorSpec[COLOR_FMARK].Blue
  481.                         );
  482.                     toggle = ! toggle;
  483.                 }
  484.                 chkabort();
  485.                 break;
  486.  
  487.             /* -------------------------------------------------------- */
  488.             /* Mousebuttons, select start and end square for moves        */
  489.             /* -------------------------------------------------------- */
  490.  
  491.             case IDCMP_MOUSEBUTTONS:
  492.                 if ( mustredraw ) {
  493.                     UpdateDisplay(0, 0, 1, 0);
  494.                     mustredraw = FALSE;
  495.                 }
  496.                 if ( ! selected ) {
  497.                     if ( ( CODE(msg) & IECODE_UP_PREFIX ) && MFeld(msg, &sq1) ) {
  498.                         if ( color[sq1] == opponent ) {
  499.                             selected = TRUE;
  500.                             MarkField(sq1);
  501.                         }
  502.                     }
  503.                 }
  504.                 else {
  505.                     if ( ( CODE(msg) & IECODE_UP_PREFIX ) && MFeld(msg, &sq2) ) {
  506.                         if ( color[sq2] != opponent ) {
  507.                             s[0] = 'a' + (sq1 & 7);
  508.                             s[1] = '1' + (sq1 / 8);
  509.                             s[2] = 'a' + (sq2 & 7);
  510.                             s[3] = '1' + (sq2 / 8);
  511.                             player = opponent;
  512.                             ok = VerifyMove(s, 0, &mv);
  513.                             if ( ok && mv != hint )
  514.                                 Sdepth    =
  515.                                 ft        = 0;
  516.                             UnMarkField(sq1);
  517.                             selected = FALSE;
  518.                         }
  519.                     }
  520.                 }
  521.                 break;
  522.  
  523.             /* -------------------------------------------------------- */
  524.             /* Gadget selection, currently none defined                    */
  525.             /* -------------------------------------------------------- */
  526.  
  527.             case IDCMP_GADGETUP:
  528.                 break;
  529.  
  530.             /* -------------------------------------------------------- */
  531.             /* Menu selection                                            */
  532.             /* -------------------------------------------------------- */
  533.  
  534.             case IDCMP_MENUPICK:
  535.                 if ( mustredraw ) {
  536.                     UpdateDisplay(0, 0, 1, 0);
  537.                     mustredraw = FALSE;
  538.                 }
  539.                 if ( selected ) {
  540.                     UnMarkField(sq1);
  541.                     selected = FALSE;
  542.                 }
  543.                 switch( CODE(msg) ) {
  544.                     case PROJECT_ABOUT:
  545.                         About();
  546.                         break;
  547.                     case PROJECT_NEWGAME:
  548.                         NewGame();
  549.                         break;
  550.                     case PROJECT_GETGAME:
  551.                         GetGame();
  552.                         break;
  553.                     case PROJECT_SAVEGAME:
  554.                         SaveGame();
  555.                         break;
  556.                     case PROJECT_SAVEEXT:
  557.                         SaveGame();
  558.                         break;
  559.                     case PROJECT_LISTGAME:
  560.                         ListGame();
  561.                         break;
  562.                     case PROJECT_QUIT:
  563.                         quit = true;
  564.                         break;
  565.                     case EDIT_EDITBOARD:
  566.                         EditBoard();
  567.                         break;
  568.                     case EDIT_GAMEDATA:
  569.                         PartieData();
  570.                         break;
  571.                     case EDIT_FORCE:
  572.                         force = ! force;
  573.                         break;
  574.                     case GAME_UNDO:
  575.                         if ( GameCnt >= 0 )
  576.                             Undo();
  577.                         break;
  578.                     case GAME_REMOVE:
  579.                         if ( GameCnt >= 1 ) {
  580.                             Undo();
  581.                             Undo();
  582.                         }
  583.                         break;
  584.                     case GAME_HINT:
  585.                         GiveHint();
  586.                         break;
  587.                     case GAME_SWITCHSIDES:
  588.                         computer    = otherside[computer];
  589.                         opponent    = otherside[opponent];
  590.                         force        = false;
  591.                         Sdepth        = 0;
  592.                         ok            = true;
  593.                         break;
  594.                     case GAME_COMPUTERWHITE:
  595.                         computer    = white;
  596.                         opponent    = black;
  597.                         ok            = true;
  598.                         force        = false;
  599.                         Sdepth        = 0;
  600.                         UpdateDisplay(0, 0, 1, 0);
  601.                         break;
  602.                     case GAME_COMPUTERBLACK:
  603.                         computer    = black;
  604.                         opponent    = white;
  605.                         ok            = true;
  606.                         force        = false;
  607.                         Sdepth        = 0;
  608.                         UpdateDisplay(0, 0, 1, 0);
  609.                         break;
  610.                     case GAME_COMPUTERBOTH:
  611.                         bothsides    = !bothsides;
  612.                         Sdepth        = 0;
  613.                         SelectMove(opponent, 1);
  614.                         ok            = true;
  615.                         UpdateDisplay(0, 0, 1, 0);
  616.                         break;
  617.                     case GAME_RESETVARS:
  618.                         ResetVars();
  619.                         break;
  620.                     case LEVEL_60_IN_005:
  621.                         TCmoves        = 60;
  622.                         TCminutes    = 5;
  623.                         TCflag        = true;
  624.                         SetTimeControl();
  625.                         UpdateDisplay(0, 0, 1, 0);
  626.                         break;
  627.                     case LEVEL_60_IN_015:
  628.                         TCmoves        = 60;
  629.                         TCminutes    = 15;
  630.                         TCflag        = true;
  631.                         SetTimeControl();
  632.                         UpdateDisplay(0, 0, 1, 0);
  633.                         break;
  634.                     case LEVEL_60_IN_030:
  635.                         TCmoves        = 60;
  636.                         TCminutes    = 30;
  637.                         TCflag        = true;
  638.                         SetTimeControl();
  639.                         UpdateDisplay(0, 0, 1, 0);
  640.                         break;
  641.                     case LEVEL_40_IN_030:
  642.                         TCmoves        = 40;
  643.                         TCminutes    = 30;
  644.                         TCflag        = true;
  645.                         SetTimeControl();
  646.                         UpdateDisplay(0, 0, 1, 0);
  647.                         break;
  648.                     case LEVEL_40_IN_060:
  649.                         TCmoves        = 40;
  650.                         TCminutes    = 60;
  651.                         TCflag        = true;
  652.                         SetTimeControl();
  653.                         UpdateDisplay(0, 0, 1, 0);
  654.                         break;
  655.                     case LEVEL_40_IN_120:
  656.                         TCmoves        = 40;
  657.                         TCminutes    = 120;
  658.                         TCflag        = true;
  659.                         SetTimeControl();
  660.                         UpdateDisplay(0, 0, 1, 0);
  661.                         break;
  662.                     case LEVEL_40_IN_240:
  663.                         TCmoves        = 40;
  664.                         TCminutes    = 240;
  665.                         TCflag        = true;
  666.                         SetTimeControl();
  667.                         UpdateDisplay(0, 0, 1, 0);
  668.                         break;
  669.                     case LEVEL_01_IN_015:
  670.                         TCmoves        = 1;
  671.                         TCminutes    = 15;
  672.                         TCflag        = false;
  673.                         SetTimeControl();
  674.                         UpdateDisplay(0, 0, 1, 0);
  675.                         break;
  676.                     case LEVEL_01_IN_060:
  677.                         TCmoves        = 1;
  678.                         TCminutes    = 60;
  679.                         TCflag        = false;
  680.                         SetTimeControl();
  681.                         UpdateDisplay(0, 0, 1, 0);
  682.                         break;
  683.                     case LEVEL_01_IN_600:
  684.                         TCmoves        = 1;
  685.                         TCminutes    = 600;
  686.                         TCflag        = false;
  687.                         SetTimeControl();
  688.                         UpdateDisplay(0, 0, 1, 0);
  689.                         break;
  690.                     case PROPERTIES_HASH:
  691.                         hashflag    = ! hashflag;
  692.                         break;
  693.                     case PROPERTIES_BOOK:
  694.                         Book        = NULL;
  695.                         break;
  696.                     case PROPERTIES_BEEP:
  697.                         beep        = ! beep;
  698.                         break;
  699.                     case PROPERTIES_POST:
  700.                         post        = ! post;
  701.                         break;
  702.                     case PROPERTIES_REVERSE:
  703.                         reverse        = ! reverse;
  704.                         UpdateDisplay(0, 0, 1, 0);
  705.                         break;
  706.                     case PROPERTIES_RANDOM:
  707.                         dither        = 6;
  708.                         break;
  709.                     case DEBUG_AWINDOW:
  710.                         ChangeAlphaWindow();
  711.                         break;
  712.                     case DEBUG_BWINDOW:
  713.                         ChangeBetaWindow();
  714.                         break;
  715.                     case DEBUG_DEPTH:
  716.                         ChangeSearchDepth();
  717.                         break;
  718.                     case DEBUG_CONTEMPT:
  719.                         SetContempt();
  720.                         break;
  721.                     case DEBUG_XWINDOW:
  722.                         ChangeXwindow();
  723.                         break;
  724.                     case DEBUG_TEST:
  725.                         t1            = time(0);
  726.                         cnt            = 0;
  727.                         for ( i = 0; i < 10000; i++ ) {
  728.                             MoveList(opponent, 2);
  729.                             cnt += TrPnt[3] - TrPnt[2];
  730.                         }
  731.                         t2            = time(0);
  732.                         rate        = cnt / (t2-t1);
  733.                         sprintf(line, "cnt = %ld  rate = %ld", cnt, rate);
  734.                         ShowMessage(line);
  735.                         break;
  736.                     case DEBUG_SHOWPOSTNVAL:
  737.                         ShowPostnValues();
  738.                         mustredraw = TRUE;
  739.                         break;
  740.                     case DEBUG_DEBUG:
  741.                         DoDebug();
  742.                         mustredraw = TRUE;
  743.                         break;
  744.                 }
  745.                 break;
  746.         }
  747.         GT_ReplyIMsg(msg);
  748.     }
  749.     
  750.     ClearMessage();
  751.     ElapsedTime(1);
  752.     if ( force ) {
  753.         computer = opponent;
  754.         opponent = otherside[computer];
  755.     }
  756.     timer(tmbuf1);
  757.     time1 = 60 * tmbuf1[0] + tmbuf1[1] / 16667;
  758.     signal(SIGINT, TerminateSearch);
  759. }
  760.  
  761. /* -------------------------------------------------------------------- */
  762. /* This is called if two successive breaks (CTRL-C) are sent             */
  763. /* -------------------------------------------------------------------- */
  764.  
  765. static void Die(int dummy)
  766. {
  767.     static struct EasyStruct es = {
  768.         sizeof(struct EasyStruct),
  769.         0,
  770.         "Please select",
  771.         "Abort?",
  772.         "Yes|No"
  773.     };
  774.  
  775.     signal(SIGINT, SIG_IGN);
  776.     if ( EasyRequestArgs(w, &es, NULL, NULL) == 1 ) ExitChess(0);
  777.     signal(SIGINT, Die);
  778. }
  779.  
  780. /* -------------------------------------------------------------------- */
  781. /* This is called if a break (CTRL-C) is sent while GNUChess thinks        */
  782. /* -------------------------------------------------------------------- */
  783.  
  784. static void TerminateSearch(int dummy)
  785. {
  786.     signal(SIGINT, SIG_IGN);
  787.     timeout        = true;
  788.     bothsides    = false;
  789.     signal(SIGINT, Die);
  790. }
  791.  
  792. /* -------------------------------------------------------------------- */
  793. /* Display current search depth                                            */
  794. /* -------------------------------------------------------------------- */
  795.  
  796. void ShowDepth(char ch)
  797. {
  798.     char buf[40];
  799.  
  800.     sprintf(buf, "Depth = %2ld%lc", Sdepth, ch);
  801.     MyText(buf, NX1 + 6, NY1 + 13);
  802. }
  803.  
  804. /* -------------------------------------------------------------------- */
  805. /* Display evaluated position score and best line found                    */
  806. /* -------------------------------------------------------------------- */
  807.  
  808. void ShowResults(short score, unsigned short *bstline, char ch)
  809. {
  810.     short    ply;
  811.     char    buf[40];
  812.     int        x, y;
  813.  
  814.     if ( post && player == computer ) {
  815.         sprintf(buf, "Score = %5ld", score);
  816.         MyText(buf, NX1 + 125, NY1 + 13);
  817.         SetAPen(rp, COLOR_TXTBCK);
  818.         RectFill(rp,
  819.             NX1 +   6, NY1 +  20,
  820.             NX1 + 231, NY1 + 100
  821.         );
  822.         for ( ply = 0; bstline[ply+1] > 0; ply++ ) {
  823.             x = NX1 + 45 * ( ply % 5 ) +  6;
  824.             y = NY1 + 17 * ( ply / 5 ) + 33;
  825.             algbr(bstline[ply+1] >> 8, bstline[ply+1] & 0xFF, false);
  826.             MyText(mvstr1, x, y);
  827.         }
  828.     }
  829. }
  830.  
  831. /* -------------------------------------------------------------------- */
  832. /* This is called every time GNUChess calculation is started            */
  833. /* -------------------------------------------------------------------- */
  834.  
  835. void SearchStartStuff(short side)
  836. {
  837.     signal(SIGINT, TerminateSearch);
  838.     if ( player == computer ) {
  839.         SetAPen(rp, COLOR_TXTBCK);
  840.         RectFill(rp, NX1, NY1, NX2, NY2);
  841.     }
  842. }
  843.  
  844. /* -------------------------------------------------------------------- */
  845. /* Display move GNUChess did                                            */
  846. /* -------------------------------------------------------------------- */
  847.  
  848. void OutputMove(void)
  849. {
  850.     char buf[40];
  851.  
  852.     if ( root->flags & epmask )
  853.         UpdateDisplay(0, 0, 1, 0);
  854.     else
  855.         UpdateDisplay(root->f, root->t, 0, root->flags & cstlmask);
  856.  
  857.     strcpy(buf, "My move is: ");
  858.     strcat(buf, mvstr1);
  859.  
  860.     MyText("                           ", TX1 + 6, TY2 - 27);
  861.     MyText(buf, TX1 + 6, TY2 - 27);
  862.  
  863.     if ( beep ) DisplayBeep(NULL);
  864.  
  865.     if ( root->flags & draw )        MyText("Draw game!              ", TX1 + 6, TY2 - 26);
  866.     else if ( root->score == -9999 ) MyText("opponent mates!         ", TX1 + 6, TY2 - 26);
  867.     else if ( root->score ==  9998 ) MyText("computer mates!         ", TX1 + 6, TY2 - 26);
  868.     else if ( root->score <  -9000 ) MyText("opponent will soon mate!", TX1 + 6, TY2 - 26);
  869.     else if ( root->score >   9000 ) MyText("computer will soon mate!", TX1 + 6, TY2 - 26);
  870.   
  871.     if ( post ) {
  872.         sprintf(buf, "Nodes     = %8ld", NodeCnt);
  873.         MyText(buf, NX1 + 6, NY1 + 132);
  874.         sprintf(buf, "Nodes/Sec = %8ld", evrate);
  875.         MyText(buf, NX1 + 6, NY1 + 144);
  876.     }
  877. }
  878.  
  879. /* -------------------------------------------------------------------- */
  880. /* Determine the time that has passed since the search was started.  If    */
  881. /* the  elapsed  time  exceeds the target (ResponseTime+ExtraTime) then    */
  882. /* set timeout to true which will terminate the search.                    */
  883. /* -------------------------------------------------------------------- */
  884.  
  885. void ElapsedTime(short iop)
  886. {
  887.     et = time(NULL) - time0;
  888.     if ( et < 0 )
  889.         et = 0;
  890.     ETnodes += 50;
  891.     if ( et > et0 || iop == 1 ) {
  892.         if ( et > ResponseTime + ExtraTime && Sdepth > 1 )
  893.             timeout = true;
  894.         et0 = et;
  895.         if ( iop == 1 ) {
  896.             time0    = time(NULL);
  897.             et0        = 0;
  898.         }
  899.         timer(tmbuf2);
  900.         time2        = 60 * tmbuf2[0] + tmbuf1[1] / 16667;
  901.         cputimer    = 100 * (time2 - time1) / HZ;
  902.         evrate        = ( cputimer > 0 ) ? (100 * NodeCnt) / (cputimer + 100 * ft) : 0;
  903.         ETnodes        = NodeCnt + 50;
  904.         UpdateClocks();
  905.     }
  906. }
  907.  
  908. static void UpdateClocks(void)
  909. {
  910.     int        m, s;
  911.     char    buf[40];
  912.  
  913.     chkabort();
  914.  
  915.     m = et / 60;
  916.     s = et % 60;
  917.     if ( TCflag ) {
  918.         m = (TimeControl.clock[player] - et) / 60;
  919.         s = (TimeControl.clock[player] - et) % 60;
  920.     }
  921.     if ( m < 0 )
  922.         m = 0;
  923.     if ( s < 0 )
  924.         s = 0;
  925.  
  926.     sprintf(buf, "%03ld:%02ld:%02ld", m / 60, m % 60, s);
  927.  
  928.     if ( player == white )
  929.         MyText(buf, TX1 + off_clock_left , TY1 + 30);
  930.     else
  931.         MyText(buf, TX1 + off_clock_right, TY1 + 30);
  932.  
  933.     if ( post ) {
  934.         sprintf(buf, "Nodes     = %8ld", NodeCnt);
  935.         MyText(buf, NX1 + 6, NY1 + 132);
  936.         sprintf(buf, "Nodes/Sec = %8ld", evrate);
  937.         MyText(buf, NX1 + 6, NY1 + 144);
  938.     }
  939. }
  940.  
  941. void SetTimeControl(void)
  942. {
  943.     if ( TCflag ) {
  944.         TimeControl.moves[white] =
  945.         TimeControl.moves[black] = TCmoves;
  946.         TimeControl.clock[white] =
  947.         TimeControl.clock[black] = 60 * TCminutes;
  948.     }
  949.     else {
  950.         TimeControl.moves[white] =
  951.         TimeControl.moves[black] =
  952.         TimeControl.clock[white] =
  953.         TimeControl.clock[black] = 0;
  954.         Level = 60 * TCminutes;
  955.     }
  956.     et = 0;
  957.     ElapsedTime(1);
  958. }
  959.  
  960. void DrawPiece(short sq)
  961. {
  962.     int piece;
  963.  
  964.     piece = ( color[sq] == black ) ? qxx[board[sq]] : pxx[board[sq]];
  965.     if ( reverse )
  966.         DrawFeld(piece, 7 - column[sq], 7 - row[sq]);
  967.     else
  968.         DrawFeld(piece, column[sq], row[sq]);
  969. }
  970.  
  971. void UpdateDisplay(short f, short t, short flag, short iscastle)
  972. {
  973.     short l; 
  974.  
  975.     if ( flag ) {
  976.         ResetGfx();
  977.         if ( bothsides ) {
  978.             MyText("Computer" , TX1 + off_comp_left  , TY1 + 13);
  979.             MyText("Computer" , TX1 + off_comp_right , TY1 + 13);
  980.         }
  981.         else
  982.             if ( computer == white ) {
  983.                 MyText("Computer" , TX1 + off_comp_left  , TY1 + 13);
  984.                 MyText("  Human  ", TX1 + off_human_right, TY1 + 13);
  985.             }
  986.             else {
  987.                 MyText("  Human  ", TX1 + off_human_left , TY1 + 13);
  988.                 MyText("Computer" , TX1 + off_comp_right , TY1 + 13);
  989.             }
  990.  
  991.         for (l = 0; l < 64; l++)
  992.             DrawPiece(l);
  993.     }
  994.     else {
  995.         DrawPiece(f);
  996.         DrawPiece(t);
  997.         if ( iscastle )
  998.             if (t > f) {
  999.                 DrawPiece(f+3);
  1000.                 DrawPiece(t-1);
  1001.             }
  1002.             else {
  1003.                 DrawPiece(f-4);
  1004.                 DrawPiece(t+1);
  1005.             }
  1006.     }
  1007. }
  1008.  
  1009. /* -------------------------------------------------------------------- */
  1010. /* Read in the Opening Book file and parse the algebraic notation for a    */
  1011. /* move  into  an  unsigned  integer  format indicating the from and to    */
  1012. /* square.   Create  a  linked  list  of  opening  lines  of play, with    */
  1013. /* entry->next  pointing to the next line and entry->move pointing to a    */
  1014. /* chunk  of  memory containing the moves.  More Opening lines of up to    */
  1015. /* 256 half moves may be added to gnuchess.book.                        */
  1016. /* -------------------------------------------------------------------- */
  1017.  
  1018. void GetOpenings(void)
  1019. {
  1020.     FILE                *fd;
  1021.     int                    c, i, j, side;
  1022.     struct BookEntry    *entry;
  1023.     unsigned short        mv, *mp, tmp[100];
  1024.  
  1025.     if ( fd = fopen("gnuchess.book", "r") ) {
  1026.         Book    = NULL;
  1027.         i        = 0;
  1028.         side    = white;
  1029.         while ( (c = parse(fd, &mv, side)) >= 0 )
  1030.             if ( c == 1 ) {
  1031.                 tmp[++i]    = mv;
  1032.                 side        = otherside[side];
  1033.             }
  1034.             else
  1035.                 if ( c == 0 && i > 0 ) {
  1036.                     entry = (struct BookEntry *)
  1037.                         AllocRemember(&rk, sizeof(struct BookEntry), MEMF_PUBLIC);
  1038.                     mp = (unsigned short *)
  1039.                         AllocRemember(&rk, (i+1) * sizeof(unsigned short), MEMF_PUBLIC);
  1040.                     entry->mv    = mp;
  1041.                     entry->next    = Book;
  1042.                     Book        = entry; 
  1043.                     for ( j = 1; j <= i; j++ )
  1044.                         *(mp++) = tmp[j];
  1045.                     *mp        =
  1046.                     i        = 0;
  1047.                     side    = white;
  1048.                 }
  1049.         fclose(fd);
  1050.     }
  1051. }
  1052.  
  1053.  
  1054. static int parse(FILE *fd, unsigned short *mv, short side)
  1055. {
  1056.     int        c, i, r1, r2, c1, c2;
  1057.     char    s[100];
  1058.  
  1059.     while ( ( c = getc(fd) ) == ' ' ) { ; }
  1060.     i        = 0;
  1061.     s[0]    = c;
  1062.     while ( c != ' ' && c != '\n' && c != EOF )
  1063.         s[++i]    =
  1064.         c        = getc(fd);
  1065.     s[++i] = '\0';
  1066.     if ( c == EOF )
  1067.         return -1;
  1068.     if ( s[0] == '!' || i < 3 ) {
  1069.         while ( c != '\n' && c != EOF )
  1070.             c = getc(fd);
  1071.         return 0;
  1072.     }
  1073.     if ( s[4] == 'o' )
  1074.         *mv = ( side == black ) ? 0x3C3A : 0x0402;
  1075.     else
  1076.         if ( s[0] == 'o' )
  1077.             *mv = ( side == black ) ? 0x3C3E : 0x0406;
  1078.         else {
  1079.             c1    = s[0] - 'a';
  1080.             r1    = s[1] - '1';
  1081.             c2    = s[2] - 'a';
  1082.             r2    = s[3] - '1';
  1083.             *mv    = ( locn[r1][c1] << 8 ) + locn[r2][c2];
  1084.         }
  1085.     return 1;
  1086. }
  1087.  
  1088. static void GetGame(void)
  1089. {
  1090.     FILE            *fd;
  1091.     char            fname[FMSIZE];
  1092.     int                c;
  1093.     BOOL            success;
  1094.     short            sq;
  1095.     unsigned short    m;
  1096.  
  1097.     success = AslRequestTags(
  1098.         freq,
  1099.         ASLFR_TitleText,    "Load Game File",
  1100.         ASLFR_InitialFile,    "chess.000",
  1101.         TAG_DONE
  1102.     );
  1103.     if ( success ) {
  1104.         strmfp(fname, freq->rf_Dir, freq->rf_File);
  1105.         if ( fd = fopen(fname, "r") ) {
  1106.             fscanf(
  1107.                 fd,
  1108.                 "%hd%hd%hd" "%hd%hd%hd%hd" "%hd%hd" "%ld%ld%hd%hd",
  1109.                 &computer,
  1110.                 &opponent,
  1111.                 &Game50,
  1112.  
  1113.                 &castld[white],
  1114.                 &castld[black],
  1115.                 &kingmoved[white],
  1116.                 &kingmoved[black],
  1117.  
  1118.                 &TCflag,
  1119.                 &OperatorTime,
  1120.  
  1121.                 &TimeControl.clock[white],
  1122.                 &TimeControl.clock[black],
  1123.                 &TimeControl.moves[white],
  1124.                 &TimeControl.moves[black]
  1125.             );
  1126.             for ( sq = 0; sq < 64; sq++ ) {
  1127.                 fscanf(fd, "%hd", &m);
  1128.                 board[sq] = (m >> 8);
  1129.                 color[sq] = (m & 0xFF);
  1130.                 if ( color[sq] == 0 )
  1131.                     color[sq] = neutral;
  1132.                 else
  1133.                     --color[sq];
  1134.             }
  1135.             GameCnt = -1;
  1136.             c = '?';
  1137.             while ( c != EOF ) {
  1138.                 ++GameCnt;
  1139.                 c = fscanf(fd, "%hd%hd%hd%ld%hd%hd%hd",
  1140.                         &GameList[GameCnt].gmove,
  1141.                         &GameList[GameCnt].score,
  1142.                         &GameList[GameCnt].depth,
  1143.                         &GameList[GameCnt].nodes,
  1144.                         &GameList[GameCnt].time,
  1145.                         &GameList[GameCnt].piece,
  1146.                         &GameList[GameCnt].color
  1147.                 );
  1148.                 if ( GameList[GameCnt].color == 0 )
  1149.                     GameList[GameCnt].color = neutral;
  1150.                 else
  1151.                     --GameList[GameCnt].color;
  1152.             }
  1153.             GameCnt--;
  1154.             if ( TimeControl.clock[white] > 0 )
  1155.                 TCflag = true;
  1156.             computer--;
  1157.             opponent--;
  1158.         }
  1159.         fclose(fd);
  1160.         InitializeStats();
  1161.         UpdateDisplay(0, 0, 1, 0);
  1162.         Sdepth = 0;
  1163.     }
  1164. }
  1165.  
  1166.  
  1167. static void SaveGame(void)
  1168. {
  1169.     FILE    *fd;
  1170.     char    fname[FMSIZE];
  1171.     short    sq, i, c;
  1172.     BOOL    success;
  1173.  
  1174.     success = AslRequestTags(
  1175.         freq,
  1176.         ASLFR_TitleText,    "Save Game File",
  1177.         ASLFR_InitialFile,    "chess.000",
  1178.         ASLFR_DoSaveMode,    TRUE,
  1179.         TAG_DONE
  1180.     );
  1181.     if ( success ) {
  1182.         strmfp(fname, freq->rf_Dir, freq->rf_File);
  1183.         if ( fd = fopen(fname, "w") ) {
  1184.             fprintf(
  1185.                 fd,
  1186.                 "%ld %ld %ld\n" "%ld %ld %ld %ld\n" "%ld %ld\n" "%ld %ld %ld %ld\n",
  1187.                 computer+1,
  1188.                 opponent+1,
  1189.                 Game50,
  1190.  
  1191.                 castld[white],
  1192.                 castld[black],
  1193.                 kingmoved[white],
  1194.                 kingmoved[black],
  1195.  
  1196.                 TCflag,
  1197.                 OperatorTime,
  1198.  
  1199.                 TimeControl.clock[white],
  1200.                 TimeControl.clock[black],
  1201.                 TimeControl.moves[white],
  1202.                 TimeControl.moves[black]
  1203.             );
  1204.             for ( sq = 0; sq < 64; sq++ ) {
  1205.                 c = (color[sq] == neutral) ? 0 : color[sq]+1;
  1206.                 fprintf(fd,"%ld\n",256*board[sq] + c);
  1207.             }
  1208.             for ( i = 0; i <= GameCnt; i++ ) {
  1209.                 c = (GameList[i].color == neutral) ? 0 : GameList[i].color + 1;
  1210.                 fprintf(
  1211.                     fd,
  1212.                     "%ld %ld %ld %ld %ld %ld %ld\n",
  1213.                     GameList[i].gmove,
  1214.                     GameList[i].score,
  1215.                     GameList[i].depth,
  1216.                     GameList[i].nodes,
  1217.                     GameList[i].time,
  1218.                     GameList[i].piece,
  1219.                     c
  1220.                 );
  1221.             }
  1222.             fclose(fd);
  1223.         }
  1224.     }
  1225. }
  1226.  
  1227.  
  1228. static void ListGame(void)
  1229. {
  1230.     FILE    *fd;
  1231.     short    i, f, t;
  1232.     BOOL    success;
  1233.     char    name[FMSIZE];
  1234.  
  1235.     success = AslRequestTags(
  1236.         freq,
  1237.         ASLFR_TitleText,    "List Game",
  1238.         ASLFR_InitialFile,    "chess.lst",
  1239.         ASLFR_DoSaveMode,    TRUE,
  1240.         TAG_DONE
  1241.     );
  1242.     if ( success ) {
  1243.         strmfp(name, freq->rf_Dir, freq->rf_File);
  1244.         if ( fd = fopen(name, "w") ) {
  1245.             fprintf(
  1246.                 fd,
  1247.                 "\n"
  1248.                 "       score  depth  nodes  time         "
  1249.                 "       score  depth  nodes  time\n"
  1250.             );
  1251.             for ( i = 0; i <= GameCnt; i++ ) {
  1252.                 f = GameList[i].gmove >> 8;
  1253.                 t = (GameList[i].gmove & 0xFF);
  1254.                 algbr(f, t, false);
  1255.                 fprintf(
  1256.                     fd,
  1257.                     (i % 2) ? "         " : "\n"
  1258.                 );
  1259.                 fprintf(
  1260.                     fd,
  1261.                     "%5s  %5ld     %2ld %6ld %5ld",
  1262.                     mvstr1,
  1263.                     GameList[i].score,
  1264.                     GameList[i].depth,
  1265.                     GameList[i].nodes,
  1266.                     GameList[i].time
  1267.                 );
  1268.             }
  1269.             fprintf(
  1270.                 fd,
  1271.                 "\n\n"
  1272.             );
  1273.             fclose(fd);
  1274.         }
  1275.     }
  1276.  
  1277. /* -------------------------------------------------------------------- */
  1278. /* Undo the most recent half-move.                                        */
  1279. /* -------------------------------------------------------------------- */
  1280.  
  1281. static void Undo(void)
  1282. {
  1283.     short f, t;
  1284.  
  1285.     f = GameList[GameCnt].gmove >> 8;
  1286.     t = GameList[GameCnt].gmove & 0xFF;
  1287.     if ( board[t] == king && distance(t, f) > 1 )
  1288.         castle(GameList[GameCnt].color, f, t, 2);
  1289.     else {
  1290.         board[f] = board[t];
  1291.         color[f] = color[t];
  1292.         board[t] = GameList[GameCnt].piece;
  1293.         color[t] = GameList[GameCnt].color;
  1294.         if ( board[f] == king )
  1295.             --kingmoved[color[f]];
  1296.     }
  1297.     if ( TCflag )
  1298.         ++TimeControl.moves[color[f]];
  1299.     GameCnt--;
  1300.     mate    = false;
  1301.     Sdepth    = 0;
  1302.     UpdateDisplay(0, 0, 1, 0);
  1303.     InitializeStats();
  1304. }
  1305.  
  1306. void ShowMessage(char *s)
  1307. {
  1308.     ClearMessage();
  1309.     MyText(s, TX1 + 6, TY2 - 10);
  1310. }
  1311.  
  1312. void ClearMessage(void)
  1313. {
  1314.     MyText("                          ", TX1 + 6, TY2 - 10);
  1315. }
  1316.  
  1317. void ClrScreen(void)
  1318. {
  1319.     ClearMessage();
  1320. }
  1321.  
  1322. void ShowCurrentMove(short pnt, short f, short t)
  1323. {
  1324.     char buf[40];
  1325.  
  1326.     algbr(f, t, false);
  1327.     sprintf(buf, "(%2ld) %4s", pnt, mvstr1);
  1328.     MyText(buf, NX1 + 6, NY1 + 114);
  1329. }
  1330.  
  1331. void ShowSidetomove(void)
  1332. {
  1333. }
  1334.  
  1335. static void ChangeAlphaWindow(void)
  1336. {
  1337.     Awindow = NumberRequest("Alpha window size:", Awindow);
  1338. }
  1339.  
  1340. static void ChangeBetaWindow(void)
  1341. {
  1342.     Bwindow = NumberRequest("Beta window size:", Bwindow);
  1343. }
  1344.  
  1345. static void GiveHint(void)
  1346. {
  1347.     char s[40];
  1348.  
  1349.     algbr((short) (hint >> 8), (short) (hint & 0xFF), false);
  1350.     strcpy(s, "try ");
  1351.     strcat(s, mvstr1);
  1352.     ShowMessage(s);
  1353. }
  1354.  
  1355. static void ChangeSearchDepth(void)
  1356. {
  1357.     MaxSearchDepth = NumberRequest("Search depth:", MaxSearchDepth);
  1358. }
  1359.  
  1360. static void SetContempt(void)
  1361. {
  1362.     contempt = NumberRequest("Contempt value:", contempt);
  1363. }
  1364.  
  1365. static void ChangeXwindow(void)
  1366. {
  1367.     xwndw = NumberRequest("X window size:", xwndw);
  1368. }
  1369.  
  1370. void SelectLevel(void)
  1371. {
  1372.     OperatorTime    = 0;
  1373.     TCmoves            = 60;
  1374.     TCminutes        = 30;
  1375.     TCflag            = true;
  1376.     SetTimeControl();
  1377.     UpdateDisplay(0, 0, 1, 0);
  1378. }
  1379.  
  1380. static void ShowPostnValues(void)
  1381. {
  1382.     short i, r, c;
  1383.     char line[40];
  1384.  
  1385.     ExaminePosition();
  1386.     for ( i = 0; i < 64; i++ ) {
  1387.         if ( reverse ) {
  1388.             r = 7-row[i];
  1389.             c = 7-column[i];
  1390.         }
  1391.         else {
  1392.             r = row[i];
  1393.             c = column[i];
  1394.         }
  1395.         c1        = color[i];
  1396.         c2        = otherside[c1];
  1397.         PC1        = PawnCnt[c1];
  1398.         PC2        = PawnCnt[c2];
  1399.         atk1    = atak[c1];
  1400.         atk2    = atak[c2];
  1401.         if ( color[i] != neutral ) {
  1402.             sprintf(line, "%3ld", SqValue(i,opponent));
  1403.             MyText(line, XPOS(c)+FELDBREITE/2-15, YPOS(r)+FELDHOEHE/2+10);
  1404.         }
  1405.     }
  1406.     ScorePosition(opponent, &i);
  1407.     sprintf(line, "Score = %ld", i);
  1408.     ShowMessage(line);
  1409. }
  1410.  
  1411. static void DoDebug(void)
  1412. {
  1413.     short k, p, i, r, c, tp, tc;
  1414.     char s[40];
  1415.  
  1416.     ExaminePosition();
  1417.     strcpy(s, StringRequest("Enter piece:", ""));
  1418.     k = (s[0] == 'w') ? white : black;
  1419.     switch ( s[1] ) {
  1420.         case 'p':
  1421.             p = pawn;
  1422.             break;
  1423.         case 'n':
  1424.             p = knight;
  1425.             break;
  1426.         case 'b':
  1427.             p = bishop;
  1428.             break;
  1429.         case 'r':
  1430.             p = rook;
  1431.             break;
  1432.         case 'q':
  1433.             p = queen;
  1434.             break;
  1435.         case 'k':
  1436.             p = king;
  1437.             break;
  1438.         default:
  1439.             p = no_piece;
  1440.             break;
  1441.     }
  1442.     for ( i = 0; i < 64; i++ ) {
  1443.         if ( reverse ) {
  1444.             r = 7-row[i];
  1445.             c = 7-column[i];
  1446.         }
  1447.         else {
  1448.             r = row[i];
  1449.             c = column[i];
  1450.         }
  1451.         tp            = board[i];
  1452.         tc            = color[i];
  1453.         board[i]    = p;
  1454.         color[i]    = k;
  1455.         c1            = k;
  1456.         c2            = otherside[c1];
  1457.         PC1            = PawnCnt[c1];
  1458.         PC2            = PawnCnt[c2];
  1459.         atk1        = atak[c1];
  1460.         atk2        = atak[c2];
  1461.         sprintf(s, "%3ld", SqValue(i,opponent));
  1462.         MyText(s, XPOS(c)+FELDBREITE/2-15, YPOS(r)+FELDHOEHE/2+10);
  1463.         board[i]    = tp;
  1464.         color[i]    = tc;
  1465.     }
  1466.     ScorePosition(opponent, &i);
  1467.     sprintf(s, "Score = %ld", i);
  1468.     ShowMessage(s);
  1469. }
  1470.  
  1471. /* -------------------------------------------------------------------- */
  1472. /* Display error message                                                */
  1473. /* -------------------------------------------------------------------- */
  1474.  
  1475. static char *errmsg[] = {
  1476.     "\0\012\014No error\0\0",                                        //  0
  1477.     "\0\012\014IGNUChess: Cannot open font times/15\0\0",            //  1
  1478.     "\0\012\014IGNUChess: Cannot open font times/18\0\0",            //  2
  1479.     "\0\012\014IGNUChess: Cannot open font courier/15\0\0",            //  3
  1480.     "\0\012\014IGNUChess: Cannot open screen\0\0",                    //  4
  1481.     "\0\012\014IGNUChess: Cannot open main window\0\0",                //  5
  1482.     "\0\012\014IGNUChess: Cannot allocate file reqester\0\0",        //    6
  1483.     "\0\012\014IGNUChess: Cannot create menu strip\0\0",            //  7
  1484.     "\0\012\014IGNUChess: Layout of menu failed\0\0",                //  8
  1485.     "\0\012\014IGNUChess: Cannot attach menu strip to window\0\0",    //  9
  1486.     "\0\012\014IGNUChess: Cannot reset menu strip\0\0",                // 10
  1487.     "\0\012\014IGNUChess: Cannot create gadget list 1\0\0",            // 11
  1488.     "\0\012\014IGNUChess: Cannot create gadget list 2\0\0",            // 12
  1489.     "\0\012\014IGNUChess: Cannot find appropriate screen mode\0\0",    // 13
  1490.     "\0\012\014IGNUChess: Cannot get dimensions of screen mode\0\0"    // 14
  1491. };
  1492.  
  1493. static void ShowError( int error )
  1494. {
  1495.     DisplayAlert( RECOVERY_ALERT, errmsg[ error ], 20 );
  1496. }
  1497.